package com.educoart.portlet;

import java.io.File;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.educoart.util.DNSUtil;
import com.educoart.util.IConstants;
import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
import com.liferay.portal.kernel.lar.UserIdStrategy;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.SystemProperties;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.Group;
import com.liferay.portal.model.LayoutSetPrototype;
import com.liferay.portal.model.Organization;
import com.liferay.portal.model.VirtualHost;
import com.liferay.portal.service.LayoutLocalServiceUtil;
import com.liferay.portal.service.LayoutSetLocalServiceUtil;
import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
import com.liferay.portal.service.OrganizationLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.service.VirtualHostLocalServiceUtil;

public class OrgSiteHelper {
	
	public static void setOrganizationSite(long companyId, long organizationId, String siteTemplate, String subdomain, boolean privateLayout) {
		
		long creatorUserId = 0l;
		try {
			creatorUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
		} catch (PortalException e) {
			e.printStackTrace();
		} catch (SystemException e) {
			e.printStackTrace();
		}		
		
		LayoutSetPrototype layoutSetPrototype = null;

		try {
			List<LayoutSetPrototype> layoutSetPrototypes = LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototypes(companyId);
			
			for (LayoutSetPrototype _layoutSetPrototype: layoutSetPrototypes) {
				if (_layoutSetPrototype.getName(Locale.US).equalsIgnoreCase(siteTemplate)) {
					layoutSetPrototype = _layoutSetPrototype;
					break;
				}
			}
		} catch (SystemException e) {
			e.printStackTrace();
		}
		if (Validator.isNull(layoutSetPrototype)) return;
		
		Map<String, String[]> parameterMap = getLayoutSetPrototypesParameters(true);
		importLayoutSetPrototype(creatorUserId, organizationId, layoutSetPrototype, privateLayout, parameterMap, true);
		
		if (!privateLayout) {
			createVirtualHost(companyId, organizationId, subdomain, privateLayout);
		}
	}
	
	private static void importLayoutSetPrototype(
			long creatorUserId, 
			long organizationId, 
			LayoutSetPrototype layoutSetPrototype, 
			boolean privateLayout, Map<String, String[]> parameterMap,
			boolean importData) {
		StringBuilder sb = new StringBuilder(importData ? 4 : 3);
		sb.append(_TEMP_DIR);
		sb.append(layoutSetPrototype.getUuid());

		if (importData) {
			sb.append("-data");
		}
		sb.append(".lar");
		File cacheFile = new File(sb.toString());
		File file = null;
		if (cacheFile.exists()) {
			Date modifiedDate = layoutSetPrototype.getModifiedDate();

			if (cacheFile.lastModified() >= modifiedDate.getTime()) {
				file = cacheFile;
			}
		}
		boolean newFile = false;
		if (Validator.isNull(file)) {
			Group group = null;
			try {
				group = layoutSetPrototype.getGroup();
			} catch (PortalException e) {
				e.printStackTrace();
			} catch (SystemException e) {
				e.printStackTrace();
			}
			try {
				file = LayoutLocalServiceUtil.exportLayoutsAsFile(
						group.getGroupId(), true, null, parameterMap,
					null, null);
			} catch (PortalException e) {
				e.printStackTrace();
			} catch (SystemException e) {
				e.printStackTrace();
			}
			newFile = true;
		}
		Group orgGroup = null;
		try {
			orgGroup = OrganizationLocalServiceUtil.getOrganization(organizationId).getGroup();
		} catch (PortalException e) {
			e.printStackTrace();
		} catch (SystemException e) {
			e.printStackTrace();
		}
		try {
			LayoutLocalServiceUtil.importLayouts(
					creatorUserId, orgGroup.getGroupId(), privateLayout, parameterMap, file);
		} catch (PortalException e) {
			e.printStackTrace();
		} catch (SystemException e) {
			e.printStackTrace();
		}

		if (newFile) {
			try {
				FileUtil.copyFile(file, cacheFile);
			} catch (Exception e) {
				e.printStackTrace();	
			}
		}
	}
	
	private static Map<String, String[]> getLayoutSetPrototypesParameters(
			boolean importData) {
		Map<String, String[]> parameterMap =
			new LinkedHashMap<String, String[]>();
		parameterMap.put(
			PortletDataHandlerKeys.CATEGORIES,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
			new String[] {Boolean.FALSE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.DELETE_PORTLET_DATA,
			new String[] {Boolean.FALSE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
			new String[] {Boolean.FALSE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
			new String[] {
				PortletDataHandlerKeys.
					LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
			});
		parameterMap.put(
			PortletDataHandlerKeys.LOGO,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.PERMISSIONS,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.PORTLET_SETUP,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.PORTLET_SETUP_ALL,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.THEME_REFERENCE,
			new String[] {Boolean.TRUE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
			new String[] {Boolean.FALSE.toString()});
		parameterMap.put(
			PortletDataHandlerKeys.USER_ID_STRATEGY,
			new String[] {UserIdStrategy.CURRENT_USER_ID});

		if (importData) {
			parameterMap.put(
				PortletDataHandlerKeys.DATA_STRATEGY,
				new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
			parameterMap.put(
				PortletDataHandlerKeys.PORTLET_DATA,
				new String[] {Boolean.TRUE.toString()});
			parameterMap.put(
				PortletDataHandlerKeys.PORTLET_DATA_ALL,
				new String[] {Boolean.TRUE.toString()});
		}
		else {
			parameterMap.put(
				PortletDataHandlerKeys.PORTLET_DATA,
				new String[] {Boolean.FALSE.toString()});
			parameterMap.put(
				PortletDataHandlerKeys.PORTLET_DATA_ALL,
				new String[] {Boolean.FALSE.toString()});
		}

		return parameterMap;
	}
	
	private static void createVirtualHost(long companyId, long organizationId, String subdomain, boolean privateLayout) {
		
		long virtualHostId = 0l;
		try {
			virtualHostId = CounterLocalServiceUtil.increment();
		} catch (SystemException e) {
			e.printStackTrace();
		}
		
		long groupId = 0l;
		try {
			Organization organization = OrganizationLocalServiceUtil.fetchOrganization(organizationId);
			groupId = organization.getGroupId();
		} catch (SystemException e) {
			e.printStackTrace();
		}
		
		VirtualHost virtualHost = VirtualHostLocalServiceUtil.createVirtualHost(virtualHostId);
		virtualHost.setCompanyId(companyId);
		
		long layoutSetId = 0l;
		try {
			layoutSetId = LayoutSetLocalServiceUtil.getLayoutSet(groupId, privateLayout).getLayoutSetId();
		} catch (PortalException e) {
			e.printStackTrace();
		} catch (SystemException e) {
			e.printStackTrace();
		}
		virtualHost.setLayoutSetId(layoutSetId);
		
		virtualHost.setHostname(subdomain + IConstants.ORG_SITE_URL);
			
		try {
			VirtualHostLocalServiceUtil.addVirtualHost(virtualHost);
		} catch (SystemException e) {
			e.printStackTrace();
		}
		
		DNSUtil.createSubDomain(companyId, subdomain);
	}
	
	private static final String _TEMP_DIR =	SystemProperties.get(SystemProperties.TMP_DIR) +
			StringPool.SLASH + "liferay" + StringPool.SLASH + "layout_set_prototype" + StringPool.SLASH;
}